import tippy from 'tippy.js'
// import tippy, { followCursor } from 'tippy.js'
import { runtimeConfig } from '../config/runtimeConfig'

/**
 * 默认配置，跟随鼠标
 */
tippy.setDefaultProps({
    // plugins: [followCursor],
    // followCursor: true,
    interactive: true,
    theme: 'light',
    allowHTML: true,
    appendTo: document.body,
    onShow() {
        if (!runtimeConfig.showTooltip) {
            return false
        }
        return
    },
})

// 指令内容
const decoderContent = [
    // ['汇编符号', '功能', '机器码'],
    ['MOVA R1,R2', '(R2)->R1', '0100 R1R2'],
    ['MOVB M,R2', '(R2)->(R0)', '0101 00R2'],
    ['MOVC R1,M', '((R0))->R1', '0110 R100'],
    ['MOVD R3,PC', '(PC)->R3', '0111 11XX'],
    ['ADD R1,R2', '(R1)+(R2)->R1', '1000 R1R2'],
    ['SUB R1,R2', '(R1)-(R2)->R1，IF(R1>R2)，THEN G=1,ELSE G=0', '1001 R1R2'],
    ['JMP', '(R3)->PC', '1010 XX11'],
    ['JG', 'IF G=1,THEN(R3)->PC', '1011 XX11'],
    ['IN R1', '将常数赋给R1', '1100 R1XX'],
    ['OUT R2', '将R2的值输出', '1101 XXR2'],
    ['MOVI IMM', '立即数IMM->(RO)', '1110 00XX IMM'],
    ['HALT', '停机', '1111 0000'],
]

let decoderTooltipHtml = ''

function createDecoderTable() {
    if (decoderTooltipHtml != '') {
        return decoderTooltipHtml
    }
    let html = `<table>
    <thead>
        <tr>
            <th>汇编符号</th>
            <th>功能</th>
            <th>机器码</th>
        </tr>
    </thead>
    <tbody>`

    for (const i of decoderContent) {
        html += ` <tr>`
        for (const item of i) {
            html += `<td>${item}</td>`
        }
        html += ` </tr>`
    }

    html += `
    </tbody>
</table>`
    decoderTooltipHtml = html
    return html
}

/**
 * 初始化提示框
 */
export function initTooltip() {
    // 下一步按钮
    tippy('.btn-step', {
        content:
            '执行一步，当你点击这个按钮时，时钟会走"上升沿+高电平"或"下降沿+低电平"的距离',
        placement: 'bottom',
    })

    // tooltip复选框
    tippy('.tooltip-actions', {
        content:
            '如果勾选了词选项，当鼠标移动到某个模块时，会显示该模块的一些说明',
        placement: 'bottom',
    })

    // pc
    tippy('.pc', {
        content: `
<h3>指令计数器PC</h3>
<p>当时钟下降沿时：</p>
<p>若in_pc为1，则addr = addr + 1</p>
<p>若ld_pc为1，则addr = in_addr</p>
`,
        placement: 'top',
    })

    // multiplexer31
    tippy('.multiplexer-3-1', {
        content: `
<h3>3-1多路复用器</h3>
<p>当s1、s0或者0、1、2的数据发生变化时：</p>
<p>根据s1s0的值，把0、1、2其中的数据送到输出</p>
`,
        placement: 'top',
    })
    // multiplexer21
    tippy('.multiplexer-2-1', {
        content: `
<h3>2-1多路复用器</h3>
<p>当s0或者0、1的数据发生变化时：</p>
<p>根据ss0的值，把0、1其中的数据送到输出</p>
`,
        placement: 'top',
    })

    // ram
    tippy('.ram', {
        content: `
<h3>存储器RAM</h3>
<p>当时钟上升沿时：</p>
<p>若RE为1，则把当前地址的值送到输出</p>
<p>若WR为1，则把BUS中的数据存储到当前地址</p>
`,
        placement: 'top',
    })

    // ir
    tippy('.ir', {
        content: `
<h3>指令寄存器IR</h3>
<p>当时钟下降沿时：</p>
<p>若ld_ir为1，从BUS中拿数据送到输出</p>
`,
        placement: 'top',
    })

    // sm
    tippy('.sm', {
        content: `
<h3>SM</h3>
<p>当时钟下降沿时：</p>
<p>若sm_en为1，则对当前值取反</p>
<p>sm的值为1时是执行指令周期，为0时是取指令周期</p>
`,
        placement: 'top',
    })

    // decoder
    tippy('.decoder', {
        content: `
<h3>指令译码器</h3>
<p>当sm的值发生变化或ir的值发生变化时时：</p>
<p>从ir中拿到数据，根据该值产生不同的指令</p>
<p>指令表如下：</p>
${createDecoderTable()}
`,
        placement: 'top',
        maxWidth: 800,
    })

    // conSignal
    tippy('.con-signal', {
        content: `
<h3>控制信号产生逻辑</h3>
<p>当输入发生变化时：</p>
<p>根据不同的指令产生控制信号</p>
`,
        placement: 'bottom',
    })

    // reg
    tippy('.reg', {
        content: `
<h3>通用寄存器</h3>
<p>当sr、dr发生变化时或者时钟下降沿：</p>
<p>若we为0，则根据sr的值把数据输出到S，根据dr的值把数据输出到D</p>
<p>若we为1，则在时钟下降沿根据dr的值，从21选择器中拿数据，放到寄存器中</p>
`,
        placement: 'top',
    })

    // au
    tippy('.au', {
        content: `
<h3>算数单元AU</h3>
<p>当au_en、ac、A、B的值发生变化时：</p>
<p>若au_en为0，则什么都不做</p>
<p>若au_en为1，ac的值为1000时，A+B</p>
<p>若au_en为1，ac的值为1001时，B-A</p>
<p>若au_en为1，ac的值为0100、0101、1101时，把A送到输出</p>
`,
        placement: 'top',
    })

    // psw
    tippy('.psw', {
        content: `
<h3>PSW</h3>
<p>当时钟下降沿时：</p>
<p>若g_en为1，gf = au_gf</p>
`,
        placement: 'top',
    })

    // input
    tippy('.input', {
        content: `
<h3>输入</h3>
<p>当in_en为1时，把输入送到总线</p>
`,
        placement: 'left',
    })
    // input
    tippy('.input .to-top-arrows.top', {
        content: `
输入默认为十进制，如果要输入二进制，请在输入框前加上0b或者末尾加上b，
例如：0b1111，1111b；
输入16进制，请在输入框前加上0x或者末尾加上h，
例如：0x1f，1fh
`,
        placement: 'top',
    })

    // output
    tippy('.output', {
        content: `
<h3>输出</h3>
<p>当out_en为1时，输出总线中的数据</p>
`,
        placement: 'top',
    })
}
